var VirtualList = require('@/components/VirtualList');
var utils = require('common/utils');
var EventEmitter = require('common/EventEmitter');
var reactive = require('common/reactive');
require('./AutoComplete.css');

module.exports = AutoComplete;

/**
 * @description Autocomplete when match keyword
 * @param {string} el
 * @example
 * new AutoComplete('body')
 */
function AutoComplete(el) {
  if (!utils.isString(el)) {
    throw new Error('el 参数必须是字符串类型');
  }
  document.querySelector(el).innerHTML =
    '<div class="input-box autocomplete-node">' +
    '<div class="input-main autocomplete-node">' +
    '<span class="input-tags autocomplete-node">' +
    '</span>' +
    '<div type="text" class="input-text autocomplete-node" style="height: 33px;" >' +
    '<input type="text" class="real-input autocomplete-node" />' +
    '</div>' +
    '</div>' +
    '<ul class="menu-list autocomplete-node" hidden>' +
    '</ul>' +
    '</div>';
  this.el = el;
}

AutoComplete.prototype.init = function (list) {
  if (!utils.isArray(list)) {
    throw new Error('list 参数必须是数组类型');
  }

  console.log('AutoComplete init:' + this.el);

  var state = {
    tags: [],
    keyword: '',
  };

  var debounceTime = 300;

  var selectedClass = 'menu-selected';

  reactive.defineReactive(state, 'keyword', state.keyword, generateFilterMenuList);

  function getTagsArray() {
    var arr = Array.from(document.querySelectorAll('.input-tag')).map(function (item) {
      return {
        id: +item.getAttribute('data-key'),
        name: item.innerText,
      };
    });
    return arr;
  }

  document.querySelector('.input-main').addEventListener('click', function () {
    document.querySelector('.real-input').focus();
  });

  function generateFilterMenuList(keyword) {
    new VirtualList(
      '.menu-list',
      keyword
        ? list.filter(function (item) {
            return item.name.toLowerCase().indexOf(keyword.toLowerCase()) !== -1;
          })
        : list,
      function (data) {
        var isSelected = getTagsArray().some(function (item) {
          return item.id === data.id;
        });

        var classNames = 'menu-item autocomplete-node';
        if (isSelected) classNames += ' ' + selectedClass;
        var li = new DOMParser()
          .parseFromString(
            '<li class="' +
              classNames +
              '" data-text="' +
              data.name +
              '" data-key="' +
              data.id +
              '">' +
              data.name +
              '</li>',
            'text/html',
          )
          .querySelector('.menu-item');
        return li;
      },
      { dynamicHeight: true, estimateListHeight: 30 },
    );
  }

  var keywords = [];
  var input = document.querySelector('.real-input');
  var isPinyin = false;

  input.addEventListener(
    'compositionstart',
    utils.debounce(
      function (e) {
        console.log(e.target.value, 'compositionstart');
        isPinyin = true;
      },
      150,
      true,
    ),
  );

  input.addEventListener(
    'compositionend',
    utils.debounce(
      function (e) {
        isPinyin = false;
        // 这里也要赋值来解决中文字符
        console.log(e.target.value, 'compositionend');
        state.keyword = e.target.value.trim();
      },
      debounceTime,
      true,
    ),
  );

  input.addEventListener(
    'input',
    utils.debounce(
      function (e) {
        if (isPinyin) return;
        console.log(e.target.value, 'input trigger');
        state.keyword = e.target.value.trim();
      },
      debounceTime,
      true,
    ),
  );

  input.addEventListener('focus', function () {
    menuList.style.display = 'block';
    generateFilterMenuList(state.keyword);
  });

  var menuList = document.querySelector('.menu-list');
  menuList.addEventListener('click', function (event) {
    var menuText = event.target.innerText;
    var id = +event.target.getAttribute('data-key');
    if (!event.target.classList.contains(selectedClass)) {
      event.target.classList.add(selectedClass);
    }
    // if ( utils.isInclude(getTagsArray(), menuText) ) return;
    if (
      getTagsArray().some(function (tag) {
        return tag.id === id;
      })
    )
      return;

    // https://www.zhangxinxu.com/wordpress/2021/02/html-string-dom/
    var tag = new DOMParser()
      .parseFromString(
        '<span class="input-tag autocomplete-node" data-key="' +
          id +
          '">' +
          menuText +
          '<span class="input-close autocomplete-node"  data-text="' +
          menuText +
          '" data-key="' +
          id +
          '"/></span>',
        'text/html',
      )
      .querySelector('.input-tag');

    keywords.push({
      name: menuText,
      id: id,
    });
    EventEmitter.emit('keywords-change', keywords);
    document.querySelector('.input-tags').appendChild(tag);
  });

  document.querySelector('.input-tags').addEventListener('click', function (event) {
    console.log('event.target.classList', event.target.classList);
    if (event.target.classList.contains('input-close')) {
      document.querySelector('.input-tags').removeChild(event.target.parentElement);
      var tagID = +event.target.getAttribute('data-key');
      console.log(
        'click tag',
        document.querySelector('.menu-item[data-key="' + tagID + '"]'),
      );
      var menuItem = document.querySelector('.menu-item[data-key="' + tagID + '"]');
      if (!menuItem) return;
      var menuItemClasses = document.querySelector(
        '.menu-item[data-key="' + tagID + '"]',
      ).classList;
      if (menuItemClasses.contains(selectedClass)) {
        menuItemClasses.remove(selectedClass);
      }
      var index = utils.findIndex(keywords, function (item) {
        return item.id === tagID;
      });
      if (index === -1) return;
      keywords.splice(index, 1);

      EventEmitter.emit('keywords-change', keywords);
    }
  });

  document.addEventListener('click', function (event) {
    if (!event.target.classList.contains('autocomplete-node')) {
      document.querySelector('.input-box .menu-list').style.display = 'none';
    }
  });
};
